package com.dingdang.sms.allinone.sender.impl

import com.alibaba.fastjson.JSON
import com.aliyuncs.DefaultAcsClient
import com.aliyuncs.dysmsapi.model.v20170525.SendBatchSmsRequest
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest
import com.aliyuncs.http.MethodType
import com.aliyuncs.profile.DefaultProfile
import com.dingdang.sms.allinone.config.AllInOneConfigurationProperties
import com.dingdang.sms.allinone.sender.AllInOneSender
import com.dingdang.sms.allinone.sender.ResultWrapper
import com.dingdang.sms.allinone.sender.Target

class AliyunSmsSender(val properties: AllInOneConfigurationProperties) : AllInOneSender {

    private val product by lazy { "Dysmsapi" }

    private val domain by lazy { "dysmsapi.aliyuncs.com" }

    private val profile by lazy { prepareProfile() }

    private fun prepareProfile(): DefaultProfile {
        val profile = DefaultProfile.getProfile(
            properties.aliyun?.sms?.regionId,
            properties.aliyun?.sms?.accessId,
            properties.aliyun?.sms?.accessSecret
        )
        DefaultProfile.addEndpoint(
            properties.aliyun?.sms?.endpoint,
            properties.aliyun?.sms?.regionId,
            product, domain
        )
        return profile
    }

    private val acsClient by lazy { DefaultAcsClient(profile) }

    override fun send(target: Target, block: (ResultWrapper) -> Unit) {
        val result = send(target)
        block(result)
    }

    override fun send(target: Target): ResultWrapper {
        target.checkTemplateId()
        return if (target.isSingleTarget()) {
            sendToSingleTarget(target)
        } else {
            sendToMultiTarget(target)
        }
    }

    private fun sendToSingleTarget(target: Target): ResultWrapper {
        val request = SendSmsRequest()
        request.method = MethodType.POST
        request.phoneNumbers = target.mobileList!!.firstOrNull()
        request.signName = properties.aliyun?.sms?.signName
        request.templateCode = target.templateId
        request.templateParam = JSON.toJSONString(target.params)
        val response = acsClient.getAcsResponse(request)
        return if (response.code == null || response.code != "OK") {
            ResultWrapper().error(message = "短信发送失败，目标电话${target.mobileList?.firstOrNull()},失败原因${response.message}")
        } else {
            ResultWrapper().ok(message = "短信发送成功，目标电话${target.mobileList?.firstOrNull()}")
        }
    }

    private fun sendToMultiTarget(target: Target): ResultWrapper {
        val request = SendBatchSmsRequest()
        request.method = MethodType.POST
        request.phoneNumberJson = JSON.toJSONString(target.mobileList)
        request.templateCode = target.templateId
        request.templateParamJson = JSON.toJSONString(target.params)
        request.signNameJson = properties.aliyun?.sms?.signName
        val response = acsClient.getAcsResponse(request)
        return if (response.code == null || response.code != "OK") {
            ResultWrapper().error(message = "短信发送失败，目标电话${target.mobileList?.joinToString()},失败原因${response.message}")
        } else {
            ResultWrapper().ok(message = "短信发送成功，目标电话${target.mobileList?.joinToString()}")
        }
    }
}